/****************************************************************************/
/*                                                                          */
/*   FILE:    transtat.c                                                    */
/*   DATE:    13/06/97                                                      */
/*   PURPOSE: DVB-CI Transport layer - state diagram for TRANS task			*/
/*   TAB STOPS : 4															*/
/*   HISTORY:				                                 			    */
/*   Version    Date  		    Written by	     Notes	    	    		*/
/*	 1.0	    13/06/1997      SCM              Initial implementation 	*/
/*                                                                    	    */
/*--------------------------------------------------------------------------*/
/*   GENERAL COMMENTS                                                 	    */
/*																		    */
/****************************************************************************/
#include <stdio.h>
#include <memory.h>
#include "sm_trace.h"
#include "itc.h"
#include "trans.h"              /* Main Module			  	*/


extern trn_fifo_t g_trn_tab_fifo[];	/* FIFO table		*/


/*--------------------------------------------------------------------------*/
/* External Variables		                                            	*/
/*--------------------------------------------------------------------------*/
extern trpt_t g_trn_tab_tcid[];   /* tcid table   								*/

/* ======================================================================== */
/* NAME : TRPT_Action					 									*/
/* 									    									*/
/* DESCRIPTION : Activate the action associated to the current state 		*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int TRPT_Action(int trnTcidIndex, xmsg_t* pXmsg)			    
{
	int				iRet;	
	unsigned char	tag;	/* tag got from fifo		*/
	xmsg_t			xmsg;

	SM_TRACE_ENTRY(TRMOD_TRANS,"TRPT_Action() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n",
						trnTcidIndex,  pXmsg);

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Action() - after entry, trnTcidIndex=%d,tcid=%d,"
			"cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
			trnTcidIndex,
			g_trn_tab_tcid[trnTcidIndex].m_tcid, 
			GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
			g_trn_tab_tcid[trnTcidIndex].m_timerId,
			g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	switch(g_trn_tab_tcid[trnTcidIndex].m_state)
	{
	case TRN_IDLE : 	 
		iRet = TRPT_Idle(trnTcidIndex, pXmsg); 
		break;

	case TRN_CREATION :  
		iRet = TRPT_Creation(trnTcidIndex, pXmsg); 
		break;

	case TRN_ACTIVE : 	 
		iRet = TRPT_Active(trnTcidIndex, pXmsg);
		break;
			
	case TRN_POLLING : 	 
		iRet = TRPT_Polling(trnTcidIndex, pXmsg);
		/* try to send a SPDU saved in fifo */
		/* ================================ */
		if ((iRet == 1) && (g_trn_tab_tcid[trnTcidIndex].m_state == TRN_ACTIVE))
		{   
			memset(&xmsg, 0x00, sizeof(xmsg));
			if ((tag = TRPT_GetFifo(trnTcidIndex, &(xmsg.m_bd.m_spdu))))   
			{
				SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Action() - is TRN_ACTIVE, so call active process\r\n");
				xmsg.m_type = tag;	
				iRet = TRPT_Active(trnTcidIndex, &xmsg);     
			}
			FreeXmsg(&xmsg);
		}
		break;
			
	case TRN_RECEPTION : 
		iRet = TRPT_Reception(trnTcidIndex, pXmsg); 
		/* try to send a SPDU saved in fifo */
		/* ================================ */
		if ((iRet == 1) && (g_trn_tab_tcid[trnTcidIndex].m_state == TRN_ACTIVE))
		{   
			memset(&xmsg, 0x00, sizeof(xmsg));
			if ((tag = TRPT_GetFifo(trnTcidIndex, &(xmsg.m_bd.m_spdu))))   
			{
				SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Action() - is TRN_ACTIVE, so call active process\r\n");
				xmsg.m_type = tag;	
				iRet = TRPT_Active(trnTcidIndex, &xmsg);     
			}
			FreeXmsg(&xmsg);
		}
		break;
			
	case TRN_POLLMORE :	 
		iRet = TRPT_Pollmore(trnTcidIndex, pXmsg);
		/* try to send a SPDU saved in fifo */
		/* ================================ */
		if ((iRet == 1) && (g_trn_tab_tcid[trnTcidIndex].m_state == TRN_ACTIVE))
		{   
			memset(&xmsg, 0x00, sizeof(xmsg));
			if ((tag = TRPT_GetFifo(trnTcidIndex, &(xmsg.m_bd.m_spdu))))   
			{
				SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Action() - is TRN_ACTIVE, so call active process\r\n");
				xmsg.m_type = tag;	
				iRet = TRPT_Active(trnTcidIndex, &xmsg);     
			}
			FreeXmsg(&xmsg);
		}
		break;
			
	
	case TRN_DELETION :  
		iRet = TRPT_Deletion(trnTcidIndex, pXmsg);
		break;
			
	default : 
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Action() - Unknown state %s(%d)", 
							GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state),
							g_trn_tab_tcid[trnTcidIndex].m_state);
		iRet = 0;	/* Error */
		break;
	}

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Action() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Action() - return, iRet=%d\r\n", iRet);
	return iRet;	
}

                                                                          
/* ======================================================================== */
/* NAME : TRPT_Idle						 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_IDLE state						*/
/*		There is a new DVB module inserted . The Transport layer must create*/
/*		the first transport (tcid = 1) connection for this physical link	*/
/* 		The LINK task has already checked that the slot id is valid			*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*		evt :		current event (transition)								*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int TRPT_Idle(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int		iRet;
	xmsg_t	xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Idle() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Idle() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	switch(evt)
	{
	case TP_CONNECT :	
		/* Get free buffer for TPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_CREATE_T_C);		/* length = sizeof(create_t_c) */
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Idle() - can't allocate buffer for coding TPDU");
			return 0;	/* Error */
		}
	
		/* Create new transport connection with tcid = 1 and with allocated memory for the TPDU message */
		/* ============================================= */
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(create_t_c, xmsg.m_bd.m_tpdu.m_tcid, 
										NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Idle() - Can't code a create_t_c for %d slot id", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	
    
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			FreeXmsg(&xmsg);
			SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Idle() - Can't send the create_t_c for %d slot id to LINK Task", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{
			/* Set the timer waiting for the response for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */

		    /* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_CREATION;
			SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Idle() - create timer=%d, switch to TRN_CREATION\r\n", g_trn_tab_tcid[trnTcidIndex].m_timerId);
			iRet = 1;		/* Success */
		}
		break;	/* end of TP_CONNECT processing */

	case t_sb :	/* t_sb received after a delete_t_c : ignored */
		if (!g_trn_tab_tcid[trnTcidIndex].m_tag)
		{
			SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Idle() - tc tag is 0\r\n");
		}
		iRet = 1;
		break;
			
	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Idle() - :protocol error. event %s(0x%02X) received in %s(%d) state", 
					XMSG_NAME(evt), evt, 
					GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state),
					g_trn_tab_tcid[trnTcidIndex].m_state);
		iRet = 0;
		break;			
	}

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Idle() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Idle() - return, iRet=%d\r\n", iRet);

	return iRet;
}	/* end of TRN_IDLE state */


/* ======================================================================== */
/* NAME : TRPT_Creation					 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_CREATION state					*/
/*	The transport layer waits for a c_t_c_reply								*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or TRPT_Tpdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		--> free t_psmg.m_tpdu												*/
/*									  										*/
/* ======================================================================== */
int TRPT_Creation(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int			iRet;
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Creation() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Creation() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	switch(evt)
	{
	case TP_TMPEND :
		SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Creation() - is TIMEOUT, switch state to TRN_IDLE\r\n");
    	/* Set the new state */
		g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		iRet = 1;		/* Success */
		break;	/* end of TIMEOUT processing */

	case TP_DISCONNECT :				
		SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Creation() - is TP_DISCONNECT, kill timer, and switch state to TRN_IDLE\r\n");
		/* kill pending timer 	*/
		TRPT_Kill_Timer(trnTcidIndex);
    
    	/* Set the new state */
		g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		iRet = 1;		/* Success */
		break;	/* end of TP_DISCONNECT processing */

	case create_t_c :
		SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - is create_t_c\r\n"); 
    	/* Verify parameters  : only tcid, already made */
    	
		SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - create_t_c only for module\r\n"); 
		iRet = 1;		/* Success */
		break;
	case c_t_c_reply :
       	/* Verify parameters  : only tcid, already made */
        
       	/* kill pending timer 	*/
		TRPT_Kill_Timer(trnTcidIndex);

		/* send SS_TC_CREATED to Session Task */
		/* ================== */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_sndrcver		= (TRANS << 4) | SESS;
		xmsg.m_type     	= SS_TC_CREATED;
		xmsg.m_bd.m_ss_tccreated.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;

		SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - is c_t_c_reply, send SS_TC_CREATED from TRANS to SESS\r\n");		
	    /* Send the message */
   		if (!ITC_SendXmsg(&xmsg))
   		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't send the SS_TC_CREATED for %d tcid to SESS Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_tcid);
			return 0;		/* Error */
		}

   		/* state unchanged since the host is waiting for t_sb following the c_t_c_reply before to change the state */
		/* Set the timer waiting for the t_sb */
		g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */

		iRet = 1;		/* Success */
        break;		/* end of c_t_c_reply processing */

	case t_sb :
        /* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);
			
		if (xpduRcv.m_du.m_xpdu_tsb.m_SBflag == TSB_DATA_AVAILABLE)  
		{   
			/* t_sb(1) received : data available on module */
			/* send a t_rcv  : Get free buffer for TPDU message  */
			/* ============ */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_T_RCV);
			if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - can't allocate buffer for coding TPDU\r\n");
				return 0;	/* Error */
			}

			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(t_rcv, g_trn_tab_tcid[trnTcidIndex].m_tcid, NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    		if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't code a t_rcv for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				return 0;		/* Error */
			}	
    
			SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Creation() - is t_sb data available, send t_rcv from TRANS to LINK\r\n");		
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't send the t_rcv for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				iRet = 0;
			}
			else
			{   
				/* Set the timer waiting for the response for this tcid */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
		    	/* Set the new state */
				g_trn_tab_tcid[trnTcidIndex].m_state = TRN_RECEPTION;
				SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - switch state to TRN_RECEPTION\r\n");

				iRet = 1;		/* Success */
			}
		}	/* end of t_sb(1) processing */
		else //t_sb no data
		{   
			/* t_sb(0) received : no data available on module */
			/* send a tpdu(poll) */
			/* ================= */	
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_POLL);
			if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - can't allocate buffer for coding TPDU\r\n");
				return 0;	/* Error */
			}
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(t_poll, g_trn_tab_tcid[trnTcidIndex].m_tcid, NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    		if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't code a t_data_last(poll) for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				return 0;		/* Error 	   */
			}	
	    
			SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - is t_sb no data, send t_poll from TRANS to LINK\r\n");		
		    /* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't send the tpdu(poll) for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				iRet = 0;		/* Error 	   */
			}
			else
			{   
				/* Set the timer waiting for the response for this tcid */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				iRet = 1;		/* Success */
			}

			/* Set the new state */
			SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - switch state to TRN_POLLING\r\n");
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLING;

			iRet = 1;		   /* Success */
		}   /* end of t_sb(0) processing  */
		break;	/* end of t_sb processing */
			
	case delete_t_c :
       	/* Verify parameters  : only tcid, already made */
        	
       	/* kill pending timer 	*/
		TRPT_Kill_Timer(trnTcidIndex);
			
		/* Get free buffer for TPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_D_T_C_REPLY);		/* length = sizeof(d_t_c_reply) */
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - can't allocate buffer for coding TPDU\r\n");
			return 0;	/* Error */
		}

		/* send a d_t_c_reply  : the same buffer tpmsg.m_tpdu is used for TPDU */
		/* ================== */
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(d_t_c_reply, g_trn_tab_tcid[trnTcidIndex].m_tcid, NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't code a d_t_c_reply for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	
    
		SM_TRACE_ERROR(TRMOD_TRANS, "TRPT_Creation() - is delete_t_c no data, send d_t_c_reply from TRANS to LINK\r\n");		
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			FreeXmsg(&xmsg);
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - Can't send the d_t_c_reply for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{
			SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Creation() - switch state to TRN_IDLE\r\n");
		   	/* Set the new state and keep memory (*mem = 1) */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
			iRet = 1;		/* Success */
		}
        break;	/* end of delete_t_c processing */

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Creation() - protocol error. event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);
		iRet = 0;
		break;	
	} // end switch

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Creation() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Creation() - return, iRet=%d\r\n", iRet);
	return iRet;
}	



/* ======================================================================== */
/* NAME : TRPT_Active					 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_ACTIVE state						*/
/*	a transport connection exists and TPDU are exchanged on the tcid		*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or TRPT_Spdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		or TRPT_Spdu --> free t_psmg.m_tpdu									*/
/*									  										*/
/* ======================================================================== */
int TRPT_Active(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int 			iRet;	/* return code 													*/
	xmsg_t			xmsg;
	xpdu_t 		xpdu;	/* information for SPDU	*/	
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Active() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Active() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	iRet = 1;

	switch(evt) 
	{
	case TP_DISCONNECT :						
		/* send the SS_TC_DELETED message */
		/* ============================== */
		TRPT_Kill_PollTimer(trnTcidIndex);	/* kill the pending TIMEPOLL timer	*/

		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of TP_DISCONNECT processing */

	case SPDU:
	case RCVSPDU:
		TRPT_Kill_PollTimer(trnTcidIndex);	/* kill the pending TIMEPOLL timer	*/

		/* Get free buffer for TPDU message (since pXmsg points the received SPDU) */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc((unsigned short)(pXmsg->m_bd.m_spdu.m_len + T_DATA_HEADER
								+ 0)); //modify by pmy
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - can't allocate buffer for coding TPDU\r\n");
			return 0;	/* Error */
		}

		if (pXmsg->m_bd.m_spdu.m_len <= MAXTPDUSIZE)
		{
			/* Code the only TPDU and send it */
			/* ============================== */
			xpdu.m_du.m_xpdu_tdata.m_len    = pXmsg->m_bd.m_spdu.m_len + 1;		 /* Add 1 byte for Tcid */
			xpdu.m_du.m_xpdu_tdata.m_pbData  = pXmsg->m_bd.m_spdu.m_pbSpdu;          /* SPDU buffer to copy into TPDU buffer */
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(t_data_last, 
															g_trn_tab_tcid[trnTcidIndex].m_tcid, 
															&xpdu, 
															xmsg.m_bd.m_tpdu.m_pbTpdu);
   			if (xmsg.m_bd.m_tpdu.m_len <= 0) 
   			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't code a t_data_last for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				FreeXmsg(&xmsg);
				return 0;		/* Error */
			}	
		    
			g_trn_tab_tcid[trnTcidIndex].m_len   = 0;	/* SPDU entirely sent */
			g_trn_tab_tcid[trnTcidIndex].m_pbSpdu = NULL;
					
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLING;
		}	/* end of sending the TPDU */
		else
		{   /* split SPDU into TPDUs, send the first TPDU */    

			/* Code the first TPDU and send it */
			/* =============================== */
			xpdu.m_du.m_xpdu_tdata.m_len    = MAXTPDUSIZE; 
			xpdu.m_du.m_xpdu_tdata.m_pbData  = pXmsg->m_bd.m_spdu.m_pbSpdu;          /* SPDU buffer to copy into TPDU buffer */
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len  = TRPT_Code(t_data_more, 
												g_trn_tab_tcid[trnTcidIndex].m_tcid, 
												&xpdu, 
												xmsg.m_bd.m_tpdu.m_pbTpdu);
   			if (xmsg.m_bd.m_tpdu.m_len <= 0) 
   			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't code a t_data_more for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				FreeXmsg(&xmsg);
				return 0;		/* Error */
			}	
					
			/* Save and Update the SPDU pointer for the next TPDU send ; Keep memory (*mem = 1) */
			g_trn_tab_tcid[trnTcidIndex].m_pbSend = pXmsg->m_bd.m_spdu.m_pbSpdu;						/* save the complete SPDU for release when the SPDU is completly sent */
			g_trn_tab_tcid[trnTcidIndex].m_pbSpdu = pXmsg->m_bd.m_spdu.m_pbSpdu + MAXTPDUSIZE - 1;	/* Sub 1 byte for Tcid */								
			g_trn_tab_tcid[trnTcidIndex].m_len = pXmsg->m_bd.m_spdu.m_len - (MAXTPDUSIZE - 1);		/* Sub 1 byte for Tcid */

			//don't need to free m_pbSpdu, it will free after all the apdu free;
			pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;

			/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLMORE;
		}	/* end of sending the first TPDU of splitted SPDU */

		/* Send the message */
		if (!ITC_SendXmsg(&xmsg))
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't send the t_data_last for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			FreeXmsg(&xmsg);
			iRet = 0;		/* Error */
		}
		else
		{
			/* Set the timer waiting for the response for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
		}
		break;

	case t_data_last :			//pmy
	case t_data_more :			
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - is data_last/data_more, only for module\r\n");
		iRet = 0;		/* Error */
		break;
	case t_rcv:
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - is t_rcv, only for module\r\n");
		iRet = 0;		/* Error */
		break;
	case SS_DELETE_TC : 
		TRPT_Kill_PollTimer(trnTcidIndex);	/* kill the pending TIMEPOLL timer	*/

       	/* Verify parameters  : only tcid, already made */
        	
		/* Get free buffer for TPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_DELETE_T_C);		/* length = sizeof(delete_t_c) */
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - can't allocate buffer for coding TPDU\r\n");
			return 0;	/* Error */
		}

		/* send a delete_t_c */
		/* ================= */
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(delete_t_c, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
												NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't code a delete_t_c for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	
    
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			FreeXmsg(&xmsg);
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't send the delete_t_c for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{   
			/* Set the timer waiting for the response for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
			iRet = 1;		/* Success */
		}
        break;	/* end of delete_t_c processing */
			
	case TP_TMPOLL : 
		/* Get free buffer for TPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_POLL);		/* length = sizeof(t_poll) */
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - can't allocate buffer for coding TPDU\r\n");
			return 0;	/* Error */
		}

		/* send a tpdu(poll) */
		/* ================= */	
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(t_poll, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
										NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't code a t_data_last(poll) for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	
    
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			FreeXmsg(&xmsg);
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - Can't send the tpdu(poll) for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{   
			/* Set the timer waiting for the response for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLING;
			iRet = 1;		/* Success */
		}
        break;	/* end of TM_POLL processing */
			
	default :	/* protocol error, release the transport connection */
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Active() - protocol error. event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);

		/* release the transport connection */
		/* ================================ */
		iRet = TRPT_Release(trnTcidIndex);
		if (iRet)
		   	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
		break;	/* end of default processing */		
	}//end switch

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Active() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Active() - return, iRet=%d\r\n", iRet);

	return iRet;
}	


/* ======================================================================== */
/* NAME : TRPT_Polling					 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_POLLING state					*/
/*	a transport connection exists and a polling or complete data 			*/
/*	have been sent by the host : wait for an answer to t_data_last 			*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or TRPT_Spdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		or TPRT_Spdu() --> free t_psmg.m_tpdu									*/
/*									  										*/
/* ======================================================================== */
int TRPT_Polling(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code 												*/
	int	new_index;	/* instance of the new state diagram						*/    
	xpdu_t 	xpdu;	/* information for t_c_error / new_t_c						*/
	xmsg_t	xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Polling() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Polling() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	iRet = 1;

	switch(evt)
	{
	case TP_DISCONNECT :
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);
			
		/* send the SS_TC_DELETED message */
		/* ============================== */
		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of TP_DISCONNECT processing */

	case t_rcv : //add by pmy
		xpduRcv.m_du.m_xpdu_tsb.m_SBflag = 0;
		
	case t_sb : 
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);
			
		if (xpduRcv.m_du.m_xpdu_tsb.m_SBflag == TSB_DATA_AVAILABLE)  
		{   
			/* t_sb(1) received : data available on module */
			/* send a t_rcv  : the same buffer tpmsg.m_tpdu is used for TPDU */
			/* ============ */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_tpdu.m_pbTpdu = pXmsg->m_bd.m_tpdu.m_pbTpdu;
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len      = TRPT_Code(t_rcv, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
											NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    		if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a t_rcv for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				return 0;		/* Error */
			}	
    
			 /* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the t_rcv for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				iRet = 0;		/* Error */
			}
			else
			{   
				pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;
				/* Set the timer waiting for the response for this tcid */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
		    	/* Set the new state */
				g_trn_tab_tcid[trnTcidIndex].m_state = TRN_RECEPTION;
			}
		}	/* end of t_sb(1) processing */
		else
		{   
			memset(&xmsg, 0x00, sizeof(xmsg));
			/* t_sb(0) received : no data available on module */
			/* if a SPDU is being sent, continue to send it (next TPDU) */ 								
			if ((g_trn_tab_tcid[trnTcidIndex].m_len > 0) && (g_trn_tab_tcid[trnTcidIndex].m_pbSpdu != NULL))
			{
				xpdu.m_du.m_xpdu_tdata.m_pbData = g_trn_tab_tcid[trnTcidIndex].m_pbSpdu;    /* SPDU buffer to copy into TPDU buffer */
				xmsg.m_sndrcver	    = (TRANS << 4) | LINK;
				xmsg.m_type      = TPDU;
				xmsg.m_bd.m_tpdu.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;	/* re-use the current buffer */
				xmsg.m_bd.m_tpdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;

				if (g_trn_tab_tcid[trnTcidIndex].m_len > MAXTPDUSIZE)
				{	
					/* several TPDU to send ; send the first here */
					/* ========================================== */
					/* Get free buffer for TPDU message */
					xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(MAXTPDUSIZE + T_DATA_HEADER);
					if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
					{
						SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - can't allocate buffer for coding TPDU\r\n");
						return 0;	/* Error */
					}

					xpdu.m_du.m_xpdu_tdata.m_len = MAXTPDUSIZE; 
					xmsg.m_bd.m_tpdu.m_len = TRPT_Code(t_data_more, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
													&xpdu, xmsg.m_bd.m_tpdu.m_pbTpdu);
    				if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    				{
						SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a t_data_more for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
						FreeXmsg(&xmsg);
						return 0;		/* Error */
					}	
					
					/* Save and Update the SPDU pointer for the next TPDU send ; Keep memory (*mem = 1) */
					g_trn_tab_tcid[trnTcidIndex].m_pbSpdu += (MAXTPDUSIZE-1);	/* Sub 1 byte for Tcid */								
					g_trn_tab_tcid[trnTcidIndex].m_len -= (MAXTPDUSIZE-1);	/* Sub 1 byte for Tcid */

				    /* Set the new state */
					g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLMORE;
				}
				else
				{	/* last TPDU to send */
					/* ================= */
					/* Get free buffer for TPDU message */
					xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc((unsigned short)(g_trn_tab_tcid[trnTcidIndex].m_len + T_DATA_HEADER));
					if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
					{
						SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - can't allocate buffer for coding TPDU\r\n");
						return 0;	/* Error */
					}

					xpdu.m_du.m_xpdu_tdata.m_len = g_trn_tab_tcid[trnTcidIndex].m_len + 1;		  /* Add 1 byte for Tcid */; 
					xmsg.m_bd.m_tpdu.m_len = TRPT_Code(t_data_last, g_trn_tab_tcid[trnTcidIndex].m_tcid, &xpdu,
									xmsg.m_bd.m_tpdu.m_pbTpdu);
					if (xmsg.m_bd.m_tpdu.m_len <= 0) 
					{
						SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a t_data_last for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
						FreeXmsg(&xmsg);
						return 0;		/* Error */
					}	
		    
					g_trn_tab_tcid[trnTcidIndex].m_len   = 0;	/* SPDU entirely sent */
                    g_trn_tab_tcid[trnTcidIndex].m_pbSpdu = NULL;

					ITC_DynFree(g_trn_tab_tcid[trnTcidIndex].m_pbSend);
					g_trn_tab_tcid[trnTcidIndex].m_pbSend = NULL;

				    /* Set the new state */
					g_trn_tab_tcid[trnTcidIndex].m_state = TRN_POLLING;
				}
	
				/* Send the message */
    			if (!ITC_SendXmsg(&xmsg))
    			{
					SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the tpdu(poll) for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
					iRet = 0;		/* Error */
				}
				else
				{
					/* Set the timer waiting for the response for this tcid */
					g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				}
			}
			else  // no SPDU is being sent
			{
	    		if (!g_trn_tab_tcid[trnTcidIndex].m_tag)
				{
					/* Set the Polling Timer */                     
	    			/* ===================== */
					g_trn_tab_tcid[trnTcidIndex].m_pollTimerId = ITC_SetTimer((unsigned short)(TMID_TRPT_POLL_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_POLLING);/* do nothing if the timer can't be created */
	    			
					/* Set the new state */
					g_trn_tab_tcid[trnTcidIndex].m_state = TRN_ACTIVE;
				}
				else
					/* request_t_c and delete_t_c : garbage the polling */
					g_trn_tab_tcid[trnTcidIndex].m_tag = 0;
			}	
		}   /* end of t_sb(0) processing  */
		break;	/* end of t_sb processing */
			
	case delete_t_c :
       	/* Verify parameters  : only tcid, already made */
        	
		// t_sb following delete_t_c management */
		g_trn_tab_tcid[trnTcidIndex].m_tag = delete_t_c;

		/* send a d_t_c_reply  : the same buffer tpmsg.m_tpdu is used for TPDU */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = pXmsg->m_bd.m_tpdu.m_pbTpdu;
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(d_t_c_reply, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
										NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a d_t_c_reply for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	
    
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the d_t_c_reply for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{
			pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;
			/* send the SS_TC_DELETED message */
			/* ============================== */
			iRet = TRPT_Disc(trnTcidIndex);
		}
		if (iRet)	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of delete_t_c processing */

	case request_t_c :
       	/* Verify parameters  : only tcid, already made */

       	/* kill pending timer 	*/
		TRPT_Kill_Timer(trnTcidIndex);

		// t_sb following request_t_c management */
		g_trn_tab_tcid[trnTcidIndex].m_tag = request_t_c;

		/* Add a new instance of the Transport State Diagram for the new transport connection 			*/						
		/* ==================================================================================			*/
		new_index = TRPT_AllocTcidIndex();	/* get the new instance for the transport state diagram 		*/
		if (new_index < 0)
		{          
			/* can't get new instance, a t_c_error is sent to the module */
			/* ========================================================= */
			memset(&xpdu, 0x00, sizeof(xpdu));
			xpdu.m_du.m_xpdu_tcerror.m_errcode = TCERR_NOTRANS;

			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_tpdu.m_pbTpdu = pXmsg->m_bd.m_tpdu.m_pbTpdu;
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len      = TRPT_Code(t_c_error, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
								&xpdu, xmsg.m_bd.m_tpdu.m_pbTpdu);
    		if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a t_c_error for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				TRPT_FreeTcidIndex(new_index);		/* free the new instance */
				return 0;						/* Error */
			}	
            	
		    /* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the t_c_error for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				TRPT_FreeTcidIndex(new_index);		/* free the new instance */
				iRet = 0;						/* Error */
			}
			else
			{
				pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;
				/* Set the timer waiting for the response for this tcid */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
			}
			
	    	/* Don't change the current state */
			return 1;					
		}	/* end of t_c_error management */
            
		g_trn_tab_tcid[new_index].m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;			
			
		/* send a new_t_c  : the same buffer tpmsg.m_tpdu is used for TPDU */
		/* ============== */
		memset(&xpdu, 0x00, sizeof(xpdu));
		xpdu.m_du.m_xpdu_newtc.m_newTcid = g_trn_tab_tcid[new_index].m_tcid;
		
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = pXmsg->m_bd.m_tpdu.m_pbTpdu;
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(new_t_c, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
								&xpdu, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a new_t_c for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			TRPT_FreeTcidIndex(new_index);		/* free the new instance */
			return 0;						/* Error */
		}	
    
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the new_t_c for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			TRPT_FreeTcidIndex(new_index);		/* free the new instance */
			iRet = 0;						/* Error */
		}
		else
		{
#ifdef WIN32
#ifdef _DEBUG
			ITC_Sleep(500);
#else
			ITC_Sleep(50);
#endif
#endif
			pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;

			/* Manage the second transport connection */
			/* ====================================== */
			pXmsg->m_type = TP_CONNECT;
			pXmsg->m_bd.m_tran_conn.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			iRet = TRPT_Idle(new_index, pXmsg);				

			/* Set the polling timer for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
    		/* Don't change the state : waiting for t_sb */
		}
        break;	/* end of request_t_c processing */

	case SPDU :
		/* Put the m_spdu in fifo */
		iRet = TRPT_PutFifo(trnTcidIndex, evt, &(pXmsg->m_bd.m_spdu));
		if (iRet)
			pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;

		/* the state is unchanged */
		break;	/* end of m_spdu processing */

	case SS_DELETE_TC :
		/* Put the message in fifo */
		iRet = TRPT_PutFifo(trnTcidIndex, evt, NULL);
			
		/* the state is unchanged */
		break;	/* end of m_spdu processing */

	case TP_TMPEND :
		/* Get free buffer for TPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_DELETE_T_C);		/* length = sizeof(delete_t_c) */
		if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - can't allocate buffer for coding TPDU\r\n");
			return 0;	/* Error */
		}

		/* send a delete_t_c */
		/* ================= */	
		xmsg.m_sndrcver		= (TRANS << 4) | LINK;
		xmsg.m_type     	= TPDU;
		xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
		xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
		xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(delete_t_c, g_trn_tab_tcid[trnTcidIndex].m_tcid,
							NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    	{
			FreeXmsg(&xmsg);
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't code a delete_t_c for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			return 0;		/* Error */
		}	

		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - Can't send the delete_t_c for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
			iRet = 0;		/* Error */
		}
		else
		{   
			pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;
			/* Set the timer waiting for the response for this tcid */
			g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
		}
        break;	/* end of TIMEOUT processing */

	case TP_TMPOLL :
		break;

	case t_data_last : //add by pmy
	case t_data_more : //add by pmy
		SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Polling() - call reception\r\n");
		iRet = TRPT_Reception(trnTcidIndex,pXmsg);
		break;

	default :	/* protocol error, release the transport connection */
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Polling() - protocol error . event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);

		/* release the transport connection */
		/* ================================ */
		iRet = TRPT_Release(trnTcidIndex);
		if (iRet)	   	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
		break;	/* end of default processing */		
	}       

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Polling() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Polling() - return, iRet=%d\r\n", iRet);
	return iRet;		
}

			

/* ======================================================================== */
/* NAME : TRPT_Pollmore					 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_POLLMORE state					*/
/*	a transport connection exists and uncomplete data have been sent 		*/
/*	by the host : wait for an answer to t_data_more				 			*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or SRPT_Tpdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		or TRPT_Spdu() --> free t_psmg.m_tpdu									*/
/*									  										*/
/* ======================================================================== */
int TRPT_Pollmore(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code 												*/
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Pollmore() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Pollmore() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	switch(evt) 
	{
	case t_sb :
		/* a module can't ask for sending data while the host sends its own data with t_data_more */
		pXmsg->m_bd.m_tpdu.m_pbTpdu[3] &= ~(0x80); // set SBflat to 0, ignore a t_sb(1)
	
		/* same process as TRN_POLLING state t_sb(0) */
		iRet = TRPT_Polling(trnTcidIndex, pXmsg);		 
		break;
					
	case TP_DISCONNECT :
	case TP_TMPEND :
	case delete_t_c :
	case SS_DELETE_TC :
	case SPDU :                       
	case t_rcv : //add by pmy		
		/* same process that for the TRN_POLLING state */
		iRet = TRPT_Polling(trnTcidIndex, pXmsg);		 
		break;
					
	default :	/* protocol error, release the transport connection (in particular : request_t_c) */
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Pollmore() - protocol error . event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);

		/* release the transport connection */
		/* ================================ */
		iRet = TRPT_Release(trnTcidIndex);
		if (iRet)
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
		break;	/* end of default processing */		
	}
	
	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Pollmore() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Pollmore() - return, iRet=%d\r\n", iRet);

	return iRet;		
}



/* ======================================================================== */
/* NAME : TRPT_Reception				 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_RECEPTION state					*/
/*	a transport connection exists and a t_rcv have been sent by the host :	*/
/*	wait for a t_data_last or t_data_more									*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or TRPT_Spdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		or TRPT_Spdu() --> free t_psmg.m_tpdu									*/
/*									  										*/
/* ======================================================================== */
int TRPT_Reception(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int				iRet;		/* return code 												*/
	unsigned char* pbSpdu;
	xmsg_t			xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Reception() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Reception() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	iRet = 1;		/* Success */
	
	switch(evt) 
	{
	case TP_DISCONNECT :
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);
			
		/* send the SS_TC_DELETED message */
		/* ============================== */
		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of TP_DISCONNECT processing */
        	
	case t_data_last :
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);

		if (xpduRcv.m_du.m_xpdu_tdata.m_len > 0)
		{
			memset(&xmsg, 0x00, sizeof(xmsg));
			if (g_trn_tab_tcid[trnTcidIndex].m_recvSize == 0)
			{	/* t_data_last without t_data_more */
				/* Get free variable size buffer for SPDU message (since pXmsg points the received TPDU) */
				/* The size's buffer is variable because it can be greater than the fixed size returned by ITC_Alloc */
				xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(xpduRcv.m_du.m_xpdu_tdata.m_len);
				if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
				{
					SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Receptioncan't allocate buffer for coding SPDU\r\n");
					return 0;	/* Error */
				}
			}
			else
			{	/* append new memory to the already allocated memory */
				xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynReAlloc(g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu, (unsigned short)(g_trn_tab_tcid[trnTcidIndex].m_recvSize + xpduRcv.m_du.m_xpdu_tdata.m_len));
				if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
				{
					SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Receptioncan't reallocate buffer for coding SPDU\r\n");
					return 0;	/* Error */
				}
				else
					g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu = xmsg.m_bd.m_spdu.m_pbSpdu;
			}
				
			/* Send a SPDU to SESS Task */
			/* ======================== */
			xmsg.m_sndrcver		= (TRANS << 4) | SESS;
			xmsg.m_type     	= SPDU;
			xmsg.m_bd.m_spdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_spdu.m_len     = xpduRcv.m_du.m_xpdu_tdata.m_len + g_trn_tab_tcid[trnTcidIndex].m_recvSize; 

			memcpy(xmsg.m_bd.m_spdu.m_pbSpdu + g_trn_tab_tcid[trnTcidIndex].m_recvSize, 
								xpduRcv.m_du.m_xpdu_tdata.m_pbData, xpduRcv.m_du.m_xpdu_tdata.m_len);
    
			/* Send the message */
   			if (!ITC_SendXmsg(&xmsg))
   			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Reception() - Can't send the SPDU for %d tcid to SESS Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_tcid);
				FreeXmsg(&xmsg);
				iRet = 0;							/* Error 		*/
			}
			else
			{
				/* Set the timer waiting for the following t_sb */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				g_trn_tab_tcid[trnTcidIndex].m_recvSize   = 0;				
				g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu = NULL;	/* m_spdu has been entirely sent  */
			}	
		}
		break;
	case t_data_more :
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);
			
		if (g_trn_tab_tcid[trnTcidIndex].m_recvSize == 0)
		{	/* first t_data_more for a new m_spdu */
			/* Get free variable size buffer for SPDU message (since pXmsg points the received TPDU) */
			/* The size's buffer is variable because it can be greater than the fixed size returned by ITC_Alloc */
			pbSpdu = ITC_DynAlloc(xpduRcv.m_du.m_xpdu_tdata.m_len);
			if (pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Reception() - can't allocate buffer for coding SPDU\r\n");
				return 0;	/* Error */
			}
			else
				g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu = pbSpdu;
		}		
        else
        {	/* append new memory to the already allocated memory */
			pbSpdu = ITC_DynReAlloc(g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu, (unsigned short)(g_trn_tab_tcid[trnTcidIndex].m_recvSize + xpduRcv.m_du.m_xpdu_tdata.m_len));
			if (pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Reception() - can't allocate buffer for coding SPDU\r\n");
				return 0;	/* Error */
			}
			else
				g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu = pbSpdu;
        }
            
		memcpy(g_trn_tab_tcid[trnTcidIndex].m_pbRcvSpdu + g_trn_tab_tcid[trnTcidIndex].m_recvSize, 
					xpduRcv.m_du.m_xpdu_tdata.m_pbData, xpduRcv.m_du.m_xpdu_tdata.m_len);
		g_trn_tab_tcid[trnTcidIndex].m_recvSize += xpduRcv.m_du.m_xpdu_tdata.m_len;
							
		/* Set the timer waiting for the following t_sb */
		g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */

		/* the state is unchanged : wait for t_sb   */
		break;	/* end of t_data_more processing    */

	case t_sb :
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);

		if (xpduRcv.m_du.m_xpdu_tsb.m_SBflag == TSB_DATA_AVAILABLE)  
		{   /* t_sb(1) received : data available on module */
			/* send a t_rcv  : the same buffer tpmsg.m_tpdu is used for TPDU */
			/* ============ */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_tpdu.m_pbTpdu = pXmsg->m_bd.m_tpdu.m_pbTpdu;
			xmsg.m_sndrcver		= (TRANS << 4) | LINK;
			xmsg.m_type     	= TPDU;
			xmsg.m_bd.m_tpdu.m_slotId  = g_trn_tab_tcid[trnTcidIndex].m_slotId;
			xmsg.m_bd.m_tpdu.m_tcid     = g_trn_tab_tcid[trnTcidIndex].m_tcid;
			xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(t_rcv, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
											NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
    		if (xmsg.m_bd.m_tpdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Reception() - Can't code a t_rcv for %d slot id\rn", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				return 0;		/* Error */
			}	
    
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Reception() - Can't send the t_rcv for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
				iRet = 0;		/* Error */
			}
			else
			{   
				pXmsg->m_bd.m_tpdu.m_pbTpdu = NULL;
				/* Set the timer waiting for the response for this tcid */
				g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
				
		    	/* the new state is unchanged */
			}
		}	/* end of t_sb(1) processing */
		else
		{   /* t_sb(0) received : no data available on module */
			if (! g_trn_tab_tcid[trnTcidIndex].m_tag)
			{
    			/* Set the Polling Timer */                     
    			/* ===================== */
				g_trn_tab_tcid[trnTcidIndex].m_pollTimerId = ITC_SetTimer((unsigned short)(TMID_TRPT_POLL_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_POLLING);/* do nothing if the timer can't be created */

				/* Set the new state */
				g_trn_tab_tcid[trnTcidIndex].m_state = TRN_ACTIVE;
			}
			else
				/* delete_t_c : garbage the polling */
				g_trn_tab_tcid[trnTcidIndex].m_tag = 0;
		}   /* end of t_sb(0) processing  */
		break;	/* end of t_sb processing */
			
	case TP_TMPEND :
	case delete_t_c :                                
	case SS_DELETE_TC :
	case SPDU :
	case t_rcv : //add by pmy
		/* same process that for the TRN_POLLING state */
		iRet = TRPT_Polling(trnTcidIndex, pXmsg);
		break;			

	default :
		SM_TRACE_ERROR(TRMOD_TRANS,"TTRPT_Reception() - protocol error . event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);

		/* release the transport connection */
		/* ================================ */
		iRet = TRPT_Release(trnTcidIndex);
		if (iRet)	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_DELETION;
		break;	/* end of default processing */		
	}		

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Reception() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Reception() - return, iRet=%d\r\n", iRet);

	return iRet;
}	



/* ======================================================================== */
/* NAME : TRPT_Deletion					 									*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the TRN_DELETION state					*/
/*	The transport layer waits for a d_t_c_reply								*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*	If the calling function is TRPT_Tpdu() or SRPT_Tpdu() and 				*/
/*		if the return code is 0 then mem is assigned with 0 in TRPT_Tpdu() 	*/
/*		or TRPT_Spdu() --> free t_psmg.m_tpdu									*/
/*									  										*/
/* ======================================================================== */
int TRPT_Deletion(int trnTcidIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;	/* return code */
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Deletion() - entry,trnTcidIndex=%d,pXmsg=0x%08X\r\n", 
					trnTcidIndex, pXmsg);
	
	evt = pXmsg->m_type;
	if (TRPT_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Deletion() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	switch(evt)
	{
	case TP_TMPEND :
		/* send the SS_TC_DELETED message */
		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of TIMEOUT processing */

	case TP_DISCONNECT :						
       	/* kill pending timer */
		TRPT_Kill_Timer(trnTcidIndex);

		/* send the SS_TC_DELETED message */
		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)
	    	/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
		break;	/* end of TP_DISCONNECT processing */

	case d_t_c_reply :
       	/* Verify parameters  : only tcid, already made */
        	
       	/* kill pending timer 	*/
		TRPT_Kill_Timer(trnTcidIndex);

		/* send the SS_TC_DELETED message */
		iRet = TRPT_Disc(trnTcidIndex);
		if (iRet)
	   		/* Set the new state */
			g_trn_tab_tcid[trnTcidIndex].m_state = TRN_IDLE;
        break;	/* end of d_t_c_reply processing */

	case t_sb :
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Deletion() - Garbage previous received t_sb\r\n");
		iRet = 1;
		break;

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Deletion() - protocol error . event 0x%x received in %d state\r\n", evt, g_trn_tab_tcid[trnTcidIndex].m_state);
		iRet = 0;
		break;	
	}		

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Deletion() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),evt=%s(0x%02X),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		XMSG_NAME(evt), evt, 
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Deletion() - return, iRet=%d\r\n", iRet);

	return iRet;
}	





/* ======================================================================== */
/* NAME : TRPT_Disc						 									*/
/* 									    									*/
/* DESCRIPTION : Action for the current transport connection associated with*/
/*	a received TP_DISCONNECT or delete_tc  									*/
/*	- Notify the SESSION Task for the current transport connection			*/  
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*									 										*/
/* OUTPUT PARAMETERS :							   							*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int TRPT_Disc(int trnTcidIndex)
{
	xmsg_t	xmsg;

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Disc() - entry, trnTcidIndex=%d\r\n", trnTcidIndex);

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Disc() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	/* make the SS_TC_DELETED message */
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_sndrcver		= (TRANS << 4) | SESS;
	xmsg.m_type     	= SS_TC_DELETED;
	xmsg.m_bd.m_ss_tc_deleted.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;

	SM_TRACE_INFO(TRMOD_TRANS, "TRPT_Disc() - send SS_TC_DELETED from TRANS to SESS\r\n");
    /* Send the message */
	if (!ITC_SendXmsg(&xmsg))
	{
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Disc() - Can't send the SS_TC_DELETED for %d tcid to SESS Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_tcid);
		return 0;		/* Error */
	}           

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Disc() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Disc() - return 1\r\n");
	return 1;		/* Success */
}


/* ======================================================================== */
/* NAME : TRPT_Release					 									*/
/* 									    									*/
/* DESCRIPTION : Action for the current transport connection when there is	*/
/*	a protocol error 														*/
/*		- Release the transport connection									*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		trnTcidIndex :		instance of the current state diagram					*/
/*		alloc :		1 : memory allocation must be made						*/
/*					0 : take the current buffer								*/
/*									 										*/
/*	the state is unchanged													*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int TRPT_Release(int trnTcidIndex)
{
	int		iRet;
	xmsg_t	xmsg;

	SM_TRACE_ENTRY(TRMOD_TRANS, "TRPT_Release() - entry,trnTcidIndex=%d,alloc=%d\r\n",
					trnTcidIndex);

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Release() - after entry, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	iRet = 1;

	/* Get free buffer for TPDU message */
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_bd.m_tpdu.m_pbTpdu = ITC_DynAlloc(S_DELETE_T_C);		/* length = sizeof(delete_t_c) */
	if (xmsg.m_bd.m_tpdu.m_pbTpdu == NULL)
	{
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Release() - can't allocate buffer for coding TPDU\r\n");
		return 0;	/* Error */
	}
		
	/* make the delete_t_c message */
	xmsg.m_sndrcver		= (TRANS << 4) | LINK;
	xmsg.m_type     	= TPDU;
	xmsg.m_bd.m_tpdu.m_slotId = g_trn_tab_tcid[trnTcidIndex].m_slotId;
	xmsg.m_bd.m_tpdu.m_tcid    = g_trn_tab_tcid[trnTcidIndex].m_tcid;
	xmsg.m_bd.m_tpdu.m_len  	= TRPT_Code(delete_t_c, g_trn_tab_tcid[trnTcidIndex].m_tcid, 
								NULL, xmsg.m_bd.m_tpdu.m_pbTpdu);
	if (xmsg.m_bd.m_tpdu.m_len <= 0) 
	{
		FreeXmsg(&xmsg);
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Release() - Can't code a delete_t_c for %d slot id\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
		return 0;		/* Error */
	}	
    
	SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Release() - send delete_t_c from TRANS to LINK\r\n");
    /* Send the message */
	if (!ITC_SendXmsg(&xmsg))
	{
		FreeXmsg(&xmsg);
		SM_TRACE_ERROR(TRMOD_TRANS,"TRPT_Release() - Can't send the delete_t_c for %d slot id to LINK Task\r\n", g_trn_tab_tcid[trnTcidIndex].m_slotId);
		iRet = 0;		/* Error */
	}
	else
	{
		/* Set the timer waiting for the response for this tcid */
		g_trn_tab_tcid[trnTcidIndex].m_timerId = ITC_SetTimer((unsigned short)(TMID_TRPT_PEND_BASE + g_trn_tab_tcid[trnTcidIndex].m_tcid), TM_TRANS);/* do nothing if the timer can't be created */
	}

	/* Send IHM_WARNING to IHM Task */

	SM_TRACE_INFO(TRMOD_TRANS,"TRPT_Release() - before return, trnTcidIndex=%d,tcid=%d,cur_state=%s(%d),timer=0x%02X,timerpoll=0x%02X\r\n", 
		trnTcidIndex,
		g_trn_tab_tcid[trnTcidIndex].m_tcid, 
		GETTRANSTATNAME(g_trn_tab_tcid[trnTcidIndex].m_state), g_trn_tab_tcid[trnTcidIndex].m_state,
		g_trn_tab_tcid[trnTcidIndex].m_timerId,
		g_trn_tab_tcid[trnTcidIndex].m_pollTimerId);

	SM_TRACE_RETURN(TRMOD_TRANS,"TRPT_Release() - return, iRet=%d\r\n", iRet);
	return iRet;
}

